package top.yogiczy.mytv.tv.ui.material

import androidx.annotation.IntRange
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.flow.debounce
/**
 * 防抖状态管理类，用于实现防抖功能
 *
 * @param wait 防抖等待时间（毫秒），必须大于等于0
 * @param func 防抖触发时执行的回调函数
 */
@Stable
class DebounceState internal constructor(
    @IntRange(from = 0) private val wait: Long,
    private val func: () -> Unit = {},
) {
    /**
     * 发送防抖信号，重新开始计时
     */
    fun send() {
        channel.trySend(wait)
    }

    private val channel = Channel<Long>(Channel.CONFLATED)

    /**
     * 观察防抖事件流，在协程作用域中收集防抖后的事件并执行回调
     */
    @OptIn(FlowPreview::class)
    suspend fun observe() {
        // 将通道转换为流，应用防抖操作，然后收集执行回调
        channel.consumeAsFlow()
            .debounce { it }
            .collect { func() }
    }
}

/**
 * 在Compose中记住防抖状态的可组合函数
 *
 * @param wait 防抖等待时间（毫秒），必须大于等于0
 * @param func 防抖触发时执行的回调函数
 * @return DebounceState 防抖状态实例
 */
@Composable
fun rememberDebounceState(
    @IntRange(from = 0) wait: Long,
    func: () -> Unit = {},
) = DebounceState(wait = wait, func = func).also {
    LaunchedEffect(it) { it.observe() }
    it.send()
}
